import WebSocket from "ws";
import { getType, jsonToString, MessageCenter, stringToJson } from "utils-lib-js";
import { config } from "../config.js";
import { setConversationTemplate } from '../helpers/index.js';
const fixStr = '';
export class NewBingSocket extends MessageCenter {
    wsConfig;
    _config;
    ws;
    bingInfo;
    convTemp;
    pingInterval;
    constructor(wsConfig, _config = config) {
        super();
        this.wsConfig = wsConfig;
        this._config = _config;
        const { bingSocketUrl } = this._config;
        const { address } = wsConfig;
        wsConfig.address = bingSocketUrl + address;
    }
    mixBingInfo(bingInfo) {
        const { conversationId, conversationSignature, clientId } = bingInfo;
        this.bingInfo = bingInfo;
        this.convTemp = setConversationTemplate({
            conversationId, conversationSignature, clientId
        });
        return this;
    }
    createWs() {
        const { wsConfig, ws } = this;
        if (ws)
            return this;
        const { address, options, protocols } = wsConfig;
        this.ws = new WebSocket(address, protocols, options);
        return this;
    }
    clearWs() {
        const { ws } = this;
        if (ws) {
            ws.close(4999, 'clearWs');
        }
        this.clearInterval();
        return this;
    }
    throwErr(err) {
        this.emit("new-bing:socket:error", err);
    }
    initEvent() {
        const { ws, error, close, open, message } = this;
        if (!ws)
            this.throwErr("ws未定义，不能初始化事件");
        ws.onerror = error;
        ws.onclose = close;
        ws.onopen = open;
        ws.onmessage = message;
        return this;
    }
    sendMessage = (opts) => {
        const { bingInfo, convTemp, ws } = this;
        const { message } = opts;
        if (!bingInfo || !convTemp)
            this.throwErr("对话信息未获取，或模板信息未配置，请重新获取信息");
        const __type = getType(message);
        let str = "";
        if (__type === "string") {
            str = message;
        }
        else if (__type === "object") {
            str = jsonToString(message);
        }
        this.emit("send-message", str);
        ws.send(str + fixStr);
    };
    message = (e) => {
        this.emit("message", e);
        onMessage.call(this, e);
    };
    open = (e) => {
        this.emit("open", e);
        const { sendMessage } = this;
        sendMessage({ message: { "protocol": "json", "version": 1 } });
    };
    close = (e) => {
        const { ws } = this;
        ws.removeAllListeners();
        this.ws = null;
        this.emit("close", e);
    };
    error = (e) => {
        this.emit("error", e);
        console.log("error");
    };
    sendPingMsg() {
        const { ws } = this;
        if (!ws)
            this.throwErr("ws未定义，无法发送Ping");
        this.startInterval();
        this.emit("init:finish", {});
    }
    startInterval() {
        this.clearInterval();
        this.pingInterval = setInterval(() => {
            this.sendMessage({ message: { "type": 6 } });
        }, 20 * 1000);
    }
    clearInterval() {
        const { pingInterval } = this;
        if (pingInterval) {
            clearInterval(pingInterval);
            this.pingInterval = null;
        }
    }
}
export function onMessage(e) {
    const dataSource = e.data.toString().split(fixStr)[0];
    const data = stringToJson(dataSource);
    const { type } = data ?? {};
    switch (type) {
        case 1:
            this.emit("message:ing", data.arguments?.[0]?.messages?.[0]?.text);
            break;
        case 2:
            this.emit("message:finish", data.item?.messages?.[1]?.text);
            break;
        case 6:
            break;
        case 7:
            console.log(data);
            break;
        default:
            this.sendPingMsg();
            break;
    }
}
export function sendConversationMessage(params) {
    const { message, invocationId } = params;
    const arg = this.convTemp.arguments[0];
    arg.message.text = message;
    arg.isStartOfSession = invocationId === 0;
    this.convTemp.invocationId = invocationId.toString();
    this.sendMessage({ message: this.convTemp });
}
